package com.yami.shop.api.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.app.dto.ShopCartOrderMergerDto;
import com.yami.shop.bean.app.param.OrderParam;
import com.yami.shop.bean.dto.OrderItemRefund;
import com.yami.shop.bean.enums.PayType;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.param.SubmitRefundApplyParam;
import com.yami.shop.bean.vo.OrderRefundVo;
import com.yami.shop.bean.vo.UserCashOutVo;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/p/orderRefund")
@Tag(name = "订单接口")
public class OrderRefundController {
    @Autowired
    private OrderService orderService;

    @Autowired
    private UserService userService;

    @Autowired
    private UserFundDetailService userFundDetailService;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private OrderRefundService orderRefundService;

    @Autowired
    private Snowflake snowflake;

    @Autowired
    private OrderSettlementService orderSettlementService;

    /**
     * 获取待退款信息
     * @param orderNumber
     * @return
     */
    @GetMapping("/getOrderRefundDetails")
    @Operation(summary = "获取退款申请信息" , description = "获取退款申请信息")
    public ServerResponseEntity<List<OrderItemRefund>> getOrderRefundDetails(String orderNumber) {
        if(StringUtils.isBlank(orderNumber)){
            return ServerResponseEntity.showFailMsg("订单号 不能为空");
        }

        Order one = orderService.lambdaQuery().eq(Order::getOrderNumber, orderNumber).one();
        if(one == null){
            return ServerResponseEntity.showFailMsg("查询订单为空");
        }

        //允许退款的订单状态
        List<Integer> integers = Arrays.asList(2, 3, 4, 5);
        if(!integers.contains(one.getStatus())){
            return ServerResponseEntity.showFailMsg("当前订单状态不能申请退款");
        }

        List<OrderItem> list = orderItemService.lambdaQuery().eq(OrderItem::getOrderNumber, orderNumber).list();
        List<OrderItemRefund> list2=new ArrayList<>();
        for(OrderItem orderItem:list){
            OrderItemRefund refund=new OrderItemRefund();

            refund.setOrderItemId(String.valueOf(orderItem.getOrderItemId()));

            refund.setProdName(orderItem.getProdName());
            refund.setSkuName(orderItem.getSkuName());
            refund.setPic(orderItem.getPic());
            refund.setPrice(new BigDecimal(orderItem.getPrice()));

            refund.setProdCount(orderItem.getProdCount());
            refund.setProductTotalAmount(new BigDecimal(orderItem.getProductTotalAmount()));

            List<OrderRefund> list1 = orderRefundService.lambdaQuery().eq(OrderRefund::getOrderNumber, orderNumber)
                    .eq(OrderRefund::getOrderItemId, orderItem.getOrderItemId())
                    .in(OrderRefund::getRefundSts, Arrays.asList(1, 2))
                    .list();

            int sum = list1.stream().mapToInt(r -> r.getGoodsNum()).sum();
            BigDecimal reduce = list1.stream().map(r -> r.getRefundAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);

            refund.setGoodsNum(sum);
            refund.setRefundAmount(reduce);

            list2.add(refund);
        }

        return ServerResponseEntity.success(list2);
    }

    @PostMapping("/submitRefundApply")
    @Operation(summary = "提交退款申请" , description = "提交退款申请")
    @Transactional
    public ServerResponseEntity<Boolean> submitRefundApply(@RequestBody List<SubmitRefundApplyParam> param) {
        if(param == null || param.isEmpty()){
            return ServerResponseEntity.showFailMsg("申请为空");
        }
        for(SubmitRefundApplyParam param1:param){
            //验证退款数量是否大于下单数量
            OrderItem byId = orderItemService.getById(param1.getOrderItemId());

            //查询已退款 + 申请中 退款数量
            List<OrderRefund> list1 = orderRefundService.lambdaQuery()
                    .eq(OrderRefund::getOrderNumber, byId.getOrderNumber())
                    .eq(OrderRefund::getOrderItemId, byId.getOrderItemId())
                    .in(OrderRefund::getRefundSts, Arrays.asList(1, 2))
                    .list();
            int sum = list1.stream().mapToInt(r -> r.getGoodsNum()).sum();
            if(byId.getProdCount() < (sum + param1.getApplyRefundNumber())){
                //下单数量 不能 小于已申请退款数量加本次申请退款数量
                throw new YamiShopBindException("下单数量 不能 小于已申请退款数量加本次申请退款数量");
            }

            Order one = orderService.lambdaQuery().eq(Order::getOrderNumber, byId.getOrderNumber()).one();
            if(one == null){
                throw new YamiShopBindException("订单为空");
            }

            OrderSettlement one1 = orderSettlementService.lambdaQuery().eq(OrderSettlement::getOrderNumber, byId.getOrderNumber()).one();
            if(one1 == null){
                throw new YamiShopBindException("订单支付信息为空");
            }

            OrderRefund refund=new OrderRefund();
            refund.setShopId(one.getShopId());
            refund.setOrderId(one.getOrderId());
            refund.setOrderNumber(one.getOrderNumber());
            refund.setOrderAmount(one.getActualTotal());
            refund.setOrderItemId(byId.getOrderItemId());

            String s = String.valueOf(snowflake.nextId());
            refund.setRefundSn(s);
            refund.setFlowTradeNo(one1.getPayNo());
            refund.setOutRefundNo(String.valueOf(snowflake.nextId()));

            refund.setPayType(one.getPayType());
            refund.setPayTypeName(PayType.instance(one.getPayType()).getPayTypeName());

            refund.setUserId(one.getUserId());
            refund.setGoodsNum(param1.getApplyRefundNumber());
            refund.setRefundAmount(new BigDecimal(byId.getPrice()).multiply(new BigDecimal(param1.getApplyRefundNumber())));

            if(param1.getApplyType() == 1){
                //仅退款
                refund.setApplyType(param1.getApplyType());
            }else if(param1.getApplyType() == 2){
                //退款退货
                refund.setApplyType(param1.getApplyType());

                if(StringUtils.isBlank(param1.getExpressName()) || StringUtils.isBlank(param1.getExpressNo())){
                    throw new YamiShopBindException("物流信息必填");
                }

                refund.setExpressName(param1.getExpressName());
                refund.setExpressNo(param1.getExpressNo());
            }

            refund.setBuyerMsg(param1.getBuyerMsg());

            refund.setRefundSts(1);
            refund.setReturnMoneySts(0);

            refund.setApplyTime(new Date());
            refund.setHandelTime(null);
            refund.setRefundTime(null);
            refund.setPhotoFiles("");
            refund.setSellerMsg(param1.getSellerMsg());

            refund.setShipTime(new Date());
            refund.setReceiveTime(null);
            refund.setReceiveMessage(null);
            orderRefundService.save(refund);
        }
        return ServerResponseEntity.success(true);
    }


    /**
     * 查看自己的退款订单
     * @param page
     * @param orderRefund
     * @return
     */
    @GetMapping("/page")
    public ServerResponseEntity<IPage<UserCashOut>> page(PageParam page, OrderRefund orderRefund) {
        String userId = SecurityUtils.getUser().getUserId();
        LambdaQueryWrapper<OrderRefund> userCashOutLambdaQueryWrapper = new LambdaQueryWrapper<>(orderRefund);

        userCashOutLambdaQueryWrapper.eq(OrderRefund::getUserId,userId);
        userCashOutLambdaQueryWrapper.orderByDesc(OrderRefund::getApplyTime);

        PageParam page1 = orderRefundService.page(page, userCashOutLambdaQueryWrapper);

        List<OrderRefund> records = page1.getRecords();

        List<OrderRefundVo> list1=new ArrayList<>();
        for (OrderRefund detail:records){
            OrderRefundVo vo=new OrderRefundVo();
            BeanUtil.copyProperties(detail,vo);

            User byId = userService.getById(detail.getUserId());
            if(byId != null){
                vo.setUserName(byId.getNickName());
            }

            OrderItem byId1 = orderItemService.getById(detail.getOrderItemId());
            if(byId1 != null){
                vo.setProdName(byId1.getProdName());
                vo.setPic(byId1.getPic());
                vo.setSkuName(byId1.getSkuName());
                vo.setProdCount(byId1.getProdCount());
            }

            list1.add(vo);
        }

        page1.setRecords(list1);
        return ServerResponseEntity.success(page1);
    }
}
